/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fi.uba.algo3.tp3.modelo.contenedor.config;

import fi.uba.algo3.tp3.modelo.contenedor.JaulaBean;
import fi.uba.algo3.tp3.modelo.contenedor.LaberintoContenedor;
import fi.uba.algo3.tp3.modelo.inanimados.Comible;
import fi.uba.algo3.tp3.modelo.inanimados.Obstaculo;
import fi.uba.algo3.tp3.modelo.inanimados.ObstaculoPared;
import fi.uba.algo3.tp3.modelo.inanimados.Punto;
import fi.uba.algo3.tp3.modelo.inanimados.PuntoBonus;
import fi.uba.algo3.tp3.modelo.inanimados.PuntoPoder;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import org.json.me.JSONArray;
import org.json.me.JSONException;
import org.json.me.JSONObject;

/**
 *
 * @author ariel
 */
public class LaberintoConfigurationLoader {

    private String filePath;
    private int bloqueAlto;
    private int bloqueAncho;

    public LaberintoConfigurationLoader(String filePath) {
        this.filePath = filePath;
    }

    private JaulaBean createJaula(JSONObject jObject) throws JSONException {
        JSONObject jaulaJSON = jObject.getJSONObject("jaula");
        int jaulaX = jaulaJSON.getInt("x");
        int jaulaY = jaulaJSON.getInt("y");
        JaulaBean jaula = new JaulaBean(jaulaX*bloqueAncho, jaulaY*bloqueAlto);

        // Son tres los bloques de la jaula
        jaula.setAlto(bloqueAlto*2);

        // Son tres los bloques de la jaula
        jaula.setAncho(bloqueAncho*3);

        jaula.generarObstaculos();

        return jaula;
    }

    private String readFile() throws FileNotFoundException, IOException {
        String content = "";
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(filePath);
            // Here BufferedInputStream is added for fast reading.
            BufferedInputStream bis = new BufferedInputStream(fis);

            BufferedReader br = new BufferedReader(new InputStreamReader(bis));

            String line = br.readLine();
            while (line != null) {
                content += line + "\r\n";
                line = br.readLine();
            }

        } catch (FileNotFoundException ex) {
            throw ex;
        } catch (IOException ex) {
            throw ex;
        } finally {
            try {
                fis.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return content;
    }

    public LaberintoContenedor loadConfiguration() throws JSONException, FileNotFoundException, IOException  {
        LaberintoContenedor laberinto = null;

        String fileContent = readFile();
        JSONObject jObject = new JSONObject(fileContent);

        int anchoLaberinto = jObject.getInt("ancho");

        int altoLaberinto = jObject.getInt("alto");
        
        bloqueAlto = jObject.getInt("bloqueAlto");

        bloqueAncho =jObject.getInt("bloqueAncho");
               
        JaulaBean jaula = createJaula(jObject);

        laberinto = new LaberintoContenedor(altoLaberinto*bloqueAlto, anchoLaberinto*bloqueAncho, jaula);

        ArrayList<Comible> comibles = createComibles(jObject.getJSONObject("comibles"));
        ArrayList<Obstaculo> obstaculos = createObstaculo(jObject.getJSONArray("obstaculos"));

        laberinto.setComibles(new LinkedList<Comible>(comibles));
        laberinto.setObstaculos(new LinkedList<Obstaculo>(obstaculos));

        return laberinto;
    }

    private ArrayList<Comible> getPuntosBonus(JSONArray puntosBonus) throws JSONException {
        ArrayList<Comible> comibles = new ArrayList<Comible>();

        for (int i = 0; i < puntosBonus.length(); i++) {
            JSONObject punto = puntosBonus.getJSONObject(i);

            int x = punto.getInt("x");
            int y = punto.getInt("y");

            PuntoBonus pb = new PuntoBonus((x*bloqueAncho)+(bloqueAncho/2), (y*bloqueAlto)+(bloqueAlto/2));
            comibles.add(pb);

        }
        return comibles;
    }

    private ArrayList<Comible> getPuntosPoder(JSONArray puntosPoder) throws JSONException {
        ArrayList<Comible> comibles = new ArrayList<Comible>();

        for (int i = 0; i < puntosPoder.length(); i++) {
            JSONObject punto = puntosPoder.getJSONObject(i);

            int x = punto.getInt("x");
            int y = punto.getInt("y");

            PuntoPoder pp = new PuntoPoder((x*bloqueAncho)+(bloqueAncho/2), (y*bloqueAlto)+(bloqueAlto/2));
            comibles.add(pp);

        }
        return comibles;
    }

    private ArrayList<Comible> getPuntos(JSONArray puntos) throws JSONException {
        ArrayList<Comible> comibles = new ArrayList<Comible>();

        for (int i = 0; i < puntos.length(); i++) {
            JSONObject punto = puntos.getJSONObject(i);

            int x = punto.getInt("x");
            int y = punto.getInt("y");

            Punto p = new Punto((x*bloqueAncho)+(bloqueAncho/2), (y*bloqueAlto)+(bloqueAlto/2));
            comibles.add(p);

        }
        return comibles;
    }

    private ArrayList<Comible> createComibles(JSONObject object) throws JSONException {
        ArrayList<Comible> comibles = new ArrayList<Comible>();
        JSONArray puntosBonus = object.getJSONArray("PuntoBonus");
        JSONArray puntosPoder = object.getJSONArray("PuntoPoder");
        JSONArray puntos = object.getJSONArray("Punto");

        comibles.addAll(getPuntosBonus(puntosBonus));
        comibles.addAll(getPuntosPoder(puntosPoder));
        comibles.addAll(getPuntos(puntos));
        return comibles;
    }

    private ArrayList<Obstaculo> createObstaculo(JSONArray array) throws JSONException {
        ArrayList<Obstaculo> obstaculos = new ArrayList<Obstaculo>();
        for (int i = 0; i < array.length(); i++) {
            JSONObject punto = array.getJSONObject(i);

            int x = punto.getInt("x");

            int y = punto.getInt("y");

            ObstaculoPared of = new ObstaculoPared(x*bloqueAncho, y*bloqueAlto);

            of.setAlto(bloqueAlto);

            of.setAncho(bloqueAncho);

            of.generarObstaculos();
            
            obstaculos.add(of);

        }
        return obstaculos;
    }

    public int getBloqueAlto() {
        return bloqueAlto;
    }

    public int getBloqueAncho() {
        return bloqueAncho;
    }

    

    

}
